#include "stm32f10x.h"                  // Device header

#define ENCODER_TIM_PERIOD  65535  // 16位计数器最大值（根据需求调整）
int16_t Encoder_Count1;  // 第一组电机编码器计数
int16_t Encoder_Count2;  // 第二组电机编码器计数
/**************************************************************************
函数功能：把TIM2初始化为编码器接口模式（PA0/PA1）
入口参数：无
返回  值：无
**************************************************************************/
void Encoder_Init_TIM2(void)
{
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;  
    TIM_ICInitTypeDef TIM_ICInitStructure;  
    GPIO_InitTypeDef GPIO_InitStructure;
    
    // 使能TIM2和GPIOA时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    
    // 配置PA0/PA1为浮空输入（编码器A/B相）
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; // 浮空输入（适合编码器推挽/开漏输出）
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    // TIM2时基初始化
    TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
    TIM_TimeBaseStructure.TIM_Prescaler = 0x0;           // 预分频器0（不分频）
    TIM_TimeBaseStructure.TIM_Period = ENCODER_TIM_PERIOD;// 自动重装值（根据编码器分辨率设置）
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
    
    // 编码器接口配置（模式3：TI1+TI2双边沿计数）
    TIM_EncoderInterfaceConfig(
        TIM2, 
        TIM_EncoderMode_TI12,         // 模式3：同时使用TI1和TI2的边沿
        TIM_ICPolarity_Rising,        // TI1（PA0）上升沿触发（可根据编码器调整）
        TIM_ICPolarity_Rising         // TI2（PA1）上升沿触发（可根据编码器调整）
    );
    
    // 输入捕获滤波配置（可选，滤除高频噪声）
    TIM_ICStructInit(&TIM_ICInitStructure);
    TIM_ICInitStructure.TIM_ICFilter = 10;               // 10次采样滤波
    TIM_ICInit(TIM2, &TIM_ICInitStructure);
    
    // 初始化计数器并使能TIM2
    TIM_SetCounter(TIM2, 0);
    TIM_Cmd(TIM2, ENABLE);
}

/**************************************************************************
函数功能：把TIM4初始化为编码器接口模式（PB6/PB7）
入口参数：无
返回  值：无
**************************************************************************/
void Encoder_Init_TIM4(void)
{
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;  
    TIM_ICInitTypeDef TIM_ICInitStructure;  
    GPIO_InitTypeDef GPIO_InitStructure;
    
    // 使能TIM4和GPIOB时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); // TIM4属于APB1总线
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // PB6/PB7属于GPIOB
    
    // 配置PB6/PB7为浮空输入（编码器A/B相）
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; // 浮空输入
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    
    // TIM4时基初始化（参数与TIM2一致，可统一宏定义）
    TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
    TIM_TimeBaseStructure.TIM_Prescaler = 0x0;           
    TIM_TimeBaseStructure.TIM_Period = ENCODER_TIM_PERIOD;
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
    
    // 编码器接口配置（PB6=TIM4_CH1，PB7=TIM4_CH2）
    TIM_EncoderInterfaceConfig(
        TIM4, 
        TIM_EncoderMode_TI12,         // 模式3
        TIM_ICPolarity_Rising,        // TI1（PB6）上升沿触发
        TIM_ICPolarity_Rising         // TI2（PB7）上升沿触发
    );
    
    // 输入捕获滤波配置
    TIM_ICStructInit(&TIM_ICInitStructure);
    TIM_ICInitStructure.TIM_ICFilter = 10;
    TIM_ICInit(TIM4, &TIM_ICInitStructure);
    
    // 初始化计数器并使能TIM4
    TIM_SetCounter(TIM4, 0);
    TIM_Cmd(TIM4, ENABLE);
}

/**************************************************************************
函数功能：单位时间读取编码器计数
入口参数：定时器编号（2或4）
返回  值：编码器计数值（正反转差分）
**************************************************************************/
int Read_Encoder(u8 TIMX)
{
    int Encoder_TIM;    
    switch(TIMX)
    {
        case 2:  
            Encoder_TIM = (short)TIM2->CNT; 
            TIM2->CNT = 0; // 清零计数器（根据需求选择是否清零）
            break;
        case 4:  
            Encoder_TIM = (short)TIM4->CNT; 
            TIM4->CNT = 0;
            break;	
        default: 
            Encoder_TIM = 0;
    }
    return Encoder_TIM;
}
